package com.vca.front.controller;

import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageInfo;
import com.vca.common.page.CommonPage;
import com.vca.common.request.CourseFilterRequest;
import com.vca.common.request.PageParamRequest;
import com.vca.common.response.ExhibitionResponse;
import com.vca.common.response.TalkResponse;
import com.vca.common.result.CommonResult;
import com.vca.common.vo.CalendarVo;
import com.vca.common.vo.CourseVo;
import com.vca.common.vo.ExhibitionVo;
import com.vca.service.service.CourseService;
import com.vca.service.service.ExhibitionService;
import com.vca.service.service.TalkService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 日历历程控制器
 *
 * @author chenbing
 * @date 2022/11/23   17:51
 */
@Slf4j
@RestController("CalendarController")
@RequestMapping("api/front/calendar")
@Api(tags = "日历历程控制器")
public class CalendarController {

    @Autowired
    private CourseService courseService;

    @Autowired
    private TalkService talkService;

    @Autowired
    private ExhibitionService exhibitionService;

    /**
     * @Description:查询当前月份的日程
     * @author:chenbing
     * @date 2023/1/28 15:34
     */
    @ApiOperation(value = "查询当前月份的日程")
    @GetMapping(value = "/getCalendar/{year}/{month}")
    public CommonResult<List<Integer>> getCalendar(@PathVariable Integer year, @PathVariable Integer month) {
        List<Integer> dates = new ArrayList<>();
        List<Integer> courseDates = courseService.getCalendar(month, year);
        if (courseDates != null) {
            courseDates.forEach(courseDate -> {
                if (!dates.contains(courseDate)) {
                    dates.add(courseDate);
                }
            });
        }
        List<Integer> exhibitionDates = exhibitionService.getCalendar(month, year);
        if (exhibitionDates != null) {
            exhibitionDates.forEach(exhibitionDate -> {
                if (!dates.contains(exhibitionDate)) {
                    dates.add(exhibitionDate);
                }
            });
        }
        List<Integer> talkDates = talkService.getCalendar(month, year);
        if (talkDates != null) {
            talkDates.forEach(talkDate -> {
                if (!dates.contains(talkDate)) {
                    dates.add(talkDate);
                }
            });
        }
        if (dates.size() > 0) {
            Collections.sort(dates);
        }
        return CommonResult.success(dates);
    }

    /**
     * @Description:历程列表
     * @Author: chenBing
     * @Date: 2022/11/23
     */
    @ApiOperation(value = "历程列表")
    @GetMapping(value = "/list")
    public CommonResult<CommonPage<CalendarVo>> list(
            @ModelAttribute PageParamRequest pageParamRequest,
            @RequestParam(value = "date") String date,
            @ApiParam(value = "0=全部 1=课程/套课 2=讲座 3=展览")
            @RequestParam(value = "type") Integer type,
            @RequestHeader(value = "language",required = false) String language
    ) {
        List<CalendarVo> calendarVoList = new ArrayList<>();
        // TODO: 2022/11/23 处理课程和套课
        CourseFilterRequest courseFilterRequest = new CourseFilterRequest();
        courseFilterRequest.setDate(date);
        if (type == 0 || type == 1) {
            courseFilterRequest.setIsSelect(false);
            List<CourseVo> courseListCalendar = courseService.getListCalendar(language,courseFilterRequest);
            if (ObjectUtil.isNotNull(courseListCalendar)) {
                for (CourseVo courseVo : courseListCalendar) {
                    CalendarVo calendarVo = new CalendarVo();
                    calendarVo.setType(courseVo.getType() == 0 ? 0 : 1);
                    calendarVo.setId(courseVo.getId());
                    calendarVo.setImagePath(courseVo.getCover());
                    if("en".equals(language)){
                        calendarVo.setTagText(courseVo.getTypeNameEn());
                        calendarVo.setName(courseVo.getNameEn());
                    }else{
                        calendarVo.setTagText(courseVo.getTypeName());
                        calendarVo.setName(courseVo.getName());
                    }
                    calendarVo.setThemeColor(courseVo.getTypeLabelColor());
                    calendarVo.setStartTime(courseVo.getSchedulingStartTime());
                    calendarVo.setEndTime(courseVo.getSchedulingEndTime());
                    calendarVo.setPrice(courseVo.getPrice());
                    calendarVo.setSeatCount(courseVo.getSeatCount());
                    CourseVo courseInfo = courseService.info(language,courseVo.getId());
                    if (ObjectUtil.isNotNull(courseInfo)) {
                        calendarVo.setIsAppointment(courseInfo.getIsAppointment());
                    }
                    calendarVoList.add(calendarVo);
                }
            }
        }
        // TODO: 2022/11/23 处理讲座
        if (type == 0 || type == 2) {
            List<TalkResponse> talkVoList = talkService.getListCalendar(date);
            if (ObjectUtil.isNotNull(talkVoList)) {
                for (TalkResponse talkResponse : talkVoList) {
                    CalendarVo calendarVo = new CalendarVo();
                    calendarVo.setType(2);
                    calendarVo.setId(talkResponse.getId());
                    calendarVo.setImagePath(talkResponse.getCover());
                    if("en".equals(language)){
                        calendarVo.setTagText(talkResponse.getTalkTypeNameEn());
                        calendarVo.setName(talkResponse.getNameEn());
                    }else{
                        calendarVo.setTagText(talkResponse.getTalkTypeName());
                        calendarVo.setName(talkResponse.getName());
                    }

                    calendarVo.setThemeColor("#B4B19E");
                    calendarVo.setStartTime(talkResponse.getSchedulingStartTime());
                    calendarVo.setEndTime(talkResponse.getSchedulingEndTime());
                    calendarVo.setPrice(talkResponse.getPrice());
                    calendarVo.setSeatCount(talkResponse.getRemainingSeatCount());
                    TalkResponse responseInfo = talkService.info(language,talkResponse.getId());
                    if (ObjectUtil.isNotNull(responseInfo)) {
                        calendarVo.setIsAppointment(responseInfo.getIsAppointment());
                    }
                    calendarVoList.add(calendarVo);
                }
            }
        }
        // TODO: 2022/11/23 处理展览
        if (type == 0 || type == 3) {
            List<ExhibitionResponse> exhibitionVoList = exhibitionService.getListCalendar(date);
            if (ObjectUtil.isNotNull(exhibitionVoList)) {
                for (ExhibitionResponse exhibitionResponse : exhibitionVoList) {
                    CalendarVo calendarVo = new CalendarVo();
                    calendarVo.setType(3);
                    calendarVo.setId(exhibitionResponse.getId());
                    calendarVo.setImagePath(exhibitionResponse.getCover());

                    if("en".equals(language)){
                        calendarVo.setTagText(exhibitionResponse.getCityNameEn());
                        calendarVo.setName(exhibitionResponse.getNameEn());
                    }else{
                        calendarVo.setTagText(exhibitionResponse.getCityName());
                        calendarVo.setName(exhibitionResponse.getName());
                    }
                    calendarVo.setThemeColor("#B4B19E");
                    calendarVo.setStartTime(exhibitionResponse.getSchedulingStartTime());
                    calendarVo.setEndTime(exhibitionResponse.getSchedulingEndTime());
                    calendarVo.setPrice(exhibitionResponse.getPrice());
                    calendarVo.setSeatCount(exhibitionResponse.getSchedulingSeatCount());
                    ExhibitionVo exhibitionInfo = exhibitionService.info(language,exhibitionResponse.getId());
                    if (ObjectUtil.isNotNull(exhibitionInfo)) {
                        calendarVo.setIsAppointment(exhibitionInfo.getIsAppointment());
                    }
                    calendarVoList.add(calendarVo);
                }
            }
            courseFilterRequest.setIsSelect(true);
            List<CourseVo> courseListCalendar = courseService.getListCalendar(language,courseFilterRequest);
            if (ObjectUtil.isNotNull(courseListCalendar)) {
                for (CourseVo courseVo : courseListCalendar) {
                    CalendarVo calendarVo = new CalendarVo();
                    calendarVo.setType(courseVo.getType() == 0 ? 0 : 1);
                    calendarVo.setId(courseVo.getId());
                    calendarVo.setImagePath(courseVo.getCover());
                    if("en".equals(language)){
                        calendarVo.setTagText(courseVo.getTypeNameEn());
                        calendarVo.setName(courseVo.getNameEn());
                    }else{
                        calendarVo.setTagText(courseVo.getTypeName());
                        calendarVo.setName(courseVo.getName());
                    }

                    calendarVo.setThemeColor(courseVo.getTypeLabelColor());
                    calendarVo.setStartTime(courseVo.getSchedulingStartTime());
                    calendarVo.setEndTime(courseVo.getSchedulingEndTime());
                    calendarVo.setPrice(courseVo.getPrice());
                    calendarVo.setSeatCount(courseVo.getSeatCount());
                    CourseVo courseInfo = courseService.info(language,courseVo.getId());
                    if (ObjectUtil.isNotNull(courseInfo)) {
                        calendarVo.setIsAppointment(courseInfo.getIsAppointment());
                    }
                    calendarVoList.add(calendarVo);
                }
            }
            if (type == 3) {
                // TODO: 2022/9/26 排序规则：现根据上课日期升序，再根据上课开始时间升序，再根据剩余席位升序
                calendarVoList = calendarVoList.stream()
                        .sorted(Comparator.comparing(CalendarVo::getType).reversed()
                                .thenComparing(Comparator.comparing(CalendarVo::getStartTime))
                                .thenComparing(Comparator.comparing(CalendarVo::getSeatCount).reversed())).collect(Collectors.toList());
                return CommonResult.success(CommonPage.restPage(startPage(calendarVoList, pageParamRequest.getPage(), pageParamRequest.getLimit())));
            }
        }
        return CommonResult.success(CommonPage.restPage(fenYe(calendarVoList, pageParamRequest)));
    }

    /**
     * @Description:处理响应结果排序和分页
     * @Author: chenBing
     * @Date: 2022/9/26
     */
    public PageInfo<CalendarVo> fenYe(List<CalendarVo> calendarVoList, PageParamRequest pageParamRequest) {
        //给list集合排序
        // TODO: 2022/9/26 排序规则：现根据上课日期升序，再根据上课开始时间升序，再根据剩余席位升序
        calendarVoList = calendarVoList.stream()
                .sorted(Comparator.comparing(CalendarVo::getType)
                        .thenComparing(Comparator.comparing(CalendarVo::getStartTime))
                        .thenComparing(Comparator.comparing(CalendarVo::getSeatCount).reversed())).collect(Collectors.toList());
        return startPage(calendarVoList, pageParamRequest.getPage(), pageParamRequest.getLimit());
    }

    /**
     * @Description:分页
     * @Author: chenBing
     * @Date: 2022/9/26
     */
    public <T> PageInfo<T> startPage(List<T> list, Integer pageNum, Integer pageSize) {
        //创建Page类
        com.github.pagehelper.Page page = new com.github.pagehelper.Page(pageNum, pageSize);
        //为Page类中的total属性赋值
        page.setTotal(list.size());
        //计算当前需要显示的数据下标起始值
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, list.size());
        //从链表中截取需要显示的子链表，并加入到Page
        if (startIndex < endIndex) {
            page.addAll(list.subList(startIndex, endIndex));
        }
        //以Page创建PageInfo
        PageInfo pageInfo = new PageInfo<>(page);
        return pageInfo;
    }
}
